Jump to content

Проблемы из-за незакрытых тегов


SelenIT
 Share

Recommended Posts

Что-то я "не нахоливорился" вчера в этой теме, хочется опять "пониспровергать основы" и подвести итог для себя (вдруг я действительно заблуждаюсь?) и для сообщества. Вот всех верстальщиков "сызмальства" учат, что незакрытые теги - бяка, ламерство, "какашкокод" и т.д., что "незакрытый тег обязательно где-нибудь аукнется", выйдет боком и т.п. Однако спецификация HTML прямо и явно разрешает опускать закрывающие теги для 18 элементов (а для 5 из них - и открывающие), а для 16 элементов закрывающий тег прямо запрещен. Отсутствие закрывающего тега не является исключительной ситуацией, поведение парсера в этом случае четко регламентировано и предсказуемо, различия в итоговой DOM сводятся к текстовым нодам на месте межтеговых пробелов и, как правило, не влияют на отображение CSS и работу скриптов.

Так чем же всё-таки опциональные теги плохи на деле? Какие реальные проблемы из-за них встречались вам на практике? Имею в виду типовые рутинные задачи, не эксперименты с новшествами (как когда-то с новыми тегами в FF3.6 у Светланы) и не валидацию под XHTML-доктайп (с ним всё понятно, целесообразности самого этого доктайпа предлагаю не касаться). Речь о штатной ситуации с обычной разметкой с HTML-доктайпом (или вообще без), с обычным потоком давно поддерживаемых элементов, для которых закрывающий тег не обязателен. Например, <p>-шек или <li>-шек. Бывало ли у вас на практике хоть раз, чтобы от пропущенного </p> или </li> верстка "ехала" (а с его добавлением - вставала на место)?

Прошу приводить именно реальные (в крайнем случае "лабораторные") примеры, а не абстрактные предположения в стиле "а вдруг там это...". Самому мне такие сходу что-то не придумываются (кроме совсем уж извратных и нежизненных, типа скрипта, тупо пересчитывающего соседние childNodes)...

Link to comment
Share on other sites

SelenIT, Дружище, ты знаешь. Я, если честно, никогда даже и не задумывался о твоём сабже. Потому что по старой привычке всегда закрывал все теги. Как-то себя приучил изначально к этому и так и пошло. :unsure:

Но щас вот до меня походу кое что начинает доходить, что мало того, что можно попусту и не закрывать, да к тому же в некоторых случаях это даже может и помочь.

Тогда самому вот интересно услышать мнение, чем, например может грозить, если я сделаю так ? По сути это даёт только плюсы, ну если конечно же мне нужно принципиально избавиться от пробелов меж строчных блоков. Но, так ли это?

Link to comment
Share on other sites

Я сам хочу узнать, для того и отдельную тему поднял. Сам вижу одни плюсы (из минусов - только косяк подсветки исходника на этом самом jsfiddle:). Даже самому как-то не верится, самому подсознательно хочется обнаружить подвох - но не получается...

Link to comment
Share on other sites

Серверные скрипты. Получил исходник чужой страницы. Нужно вырезать только текст новости, без оформления. Если из доступных средств только regexp, то найти окончание контента без закрывающих тегов становится мучительно больно. Возможно, но гораздо труднее.

Некоторые XML-парсеры (не умеющие или не подозревающие про HTML), никогда не построят нормальную DOM-структуру, и придется вручную закрывать теги. Обходится предварительной нормализацией контента при помощи того же tidy, но и эта утилита не всемогуща.

  • Like 1
Link to comment
Share on other sites

Ну, чужая страница - потемки на то и чужая, что контроля над ней у нас априори нет, поэтому приходится заранее озаботиться инструментом для ее парсинга, чтоб был как минимум не слабее tidy (типа чего-то такого или html5lib). Парсить любой HTML регулярками - тот еще гемо "челлендж", а XML-парсер может упасть и на вполне аккуратной HTML-разметке из-за пресловутых <br> вместо <br/>. Но с адекватным задаче инструментом, имхо, это не такая уж проблема.

Меня же интересуют потенциальные траблы от использования легальных вольностей HTML в собственном коде. И грань, где использование переходит в злоупотребление :)

Link to comment
Share on other sites

Sorrow +1. Более чем жизненные примеры. Для верстальщика да, вред не виден, а вот если работаешь с xml+xsl, или парсишь такой "свободный" html-код, то жизненно важным становиться закрытие всех тегов.

Link to comment
Share on other sites

а вот если работаешь с xml+xsl
Часто приходится? Именно с конечной клиентской разметкой, а не промежуточными слоями?
или парсишь такой "свободный" html-код
Так адекватному HTML-парсеру без разницы, а если нужно парсить чужой неизвестный код, всё равно приходится быть готовым к худшему. Та же html5lib, ЕМНИП, позволяет работать с любым сколь угодно кривым HTML (точнее, полученным из него DOM-деревом) как с XML-инфосетом, со всеми плюшками типа XPath/XSLT. А плохому инструменту всегда что-нибудь мешает :)
Для верстальщика да, вред не виден
...что и требовалось доказать? ;)
Link to comment
Share on other sites

Для верстальщика да, вред не виден
...что и требовалось доказать? ;)

дык я и не верстальщик :D

отсюда и другое отношение. для меня, в идеале, весь html должен быть 100% валидным xml-em, тогда и мир во всём мире наступит. а шаблонизацию, кроме как с помощью xsl запретит законодательно, её же, всех верстальщиков заставить учить вперёд html'ля :devil:

Link to comment
Share on other sites

С этой точки зрения, пожалуй, HTML вообще не должен был появляться :). Весь веб должен был бы быть изначально XMLным, веллформным, привычным к "драконовскому" контролю ошибок и т.п. Но всё же хотелось бы поговорить о суровой прозе жизни :)

Link to comment
Share on other sites

SelenIT, Блин, Илюх, а выходит, что по сути мы не может юзать незакрытые теги, потому что создадим траблы программерам, и вообще сделаем медвежью услугу всем, кроме себя :facepalmxd:

Link to comment
Share on other sites

Программеры делают себе медвежью услугу сами, когда берут инструмент не по задаче. И для XML-парсера абсолютно пофиг, закрыт <p> явно или автоматически - ему достаточно, что это не XML. А более-менее нормальные инструменты умеют парсить и то, и другое по ситуации, и в случае HTML им опять же пофиг, как что закрыто (тот же DOMDocument в PHP умеет парсить и то, и то, и преобразоывать итоговую DOM в любой из вариантов).

Если кто-то не освоил ножовку по металлу - это ж не повод не пользоваться металлом и делать всё из дерева, разве нет? ;)

Link to comment
Share on other sites

Парсить любой HTML регулярками - тот еще гемо "челлендж"

Иногда нужно добиваться максимальной скорости работы, и регулярки могут оказаться самым быстрым способом.

Меня же интересуют потенциальные траблы от использования легальных вольностей HTML в собственном коде. И грань, где использование переходит в злоупотребление :)

В собственном коде нет никаких проблем. Ты сам себе отдаешь отчет, достаточно ли такой гибкости или нет в данном случае. Проблемы возникают только на момент кроссистемного взаимодействия.

Так адекватному HTML-парсеру без разницы, а если нужно парсить чужой неизвестный код, всё равно приходится быть готовым к худшему.

В том то и дело, что если написать парсер по стандартам, то любая "кривая" страница становится невалидной и парсинг нужно останавливать. Это существенно ухудшает результативность работы некой программы, и требуются дополнительные ресурсы на предварительную нормализацию исходного кода. А так как парсеры разрешают расслаблять батоны и чудить в коде, результат не заставляет себя ждать: количество неправильных страниц множится как грибы после дождя. Вольности приводят к накладным расходам и делают в целом только хуже. Для всех.

Link to comment
Share on other sites

если написать парсер по стандартам, то любая "кривая" страница становится невалидной и парсинг нужно останавливать

Насколько я в курсе, HTML5-парсер как раз разработан с запасом устойчивости к кривизне на входе и умеет строить вменяемую DOM из практически чего угодно, нормализуя прямо по ходу парсинга (все нужные "прихватки" там по сути захардкоданы). А неправильные страницы множатся и тупо путем копипасты. По-хорошему, конечно, качество выходного кода должны бы обеспечивать инструменты публикации (те же CMS), но кто ж их всех обяжет...

Link to comment
Share on other sites

Насколько я в курсе, HTML5-парсер как раз разработан с запасом устойчивости к кривизне на входе и умеет строить вменяемую DOM из практически чего угодно, нормализуя прямо по ходу парсинга (все нужные "прихватки" там по сути захардкоданы).

Что, можно уже писать вот так? <img src="test.png">Буууу</img>

Link to comment
Share on other sites

какой профит в незакрывании тегов

Например, однозначность итоговой DOM (в частности, расположение пробельных текстовых нод - внутри элементов или между ними, что бывает критично при использовании inline-block) и независимость ее от форматирования кода. Гарантированная кроссбраузерность (IE7- всегда игнорируют закрывающие </li> внутри списков, при неявном закрытии DOM во всех браузерах одинакова). "Незначащие" закрывающие теги могут ввести в заблуждение, например, что "можно вставить блочный элемент в абзац" и привести к неприятным сюрпризам при отладке, без них о таких вещах приходится помнить, что в итоге ведет к лучшему пониманию логики кода. Да и экономия букв может быть значимой, например, в "спортивных" задачах-конкурсах типа "впихнуть что-то прикольное/полезное в 1/2/5 кБ", а также при получении больших фрагментов разметки через AJAH...

можно уже писать вот так?

Писать так нельзя :), но парсер не умрет, встретив такую бяку. В DOM попадут картинка и текстовая нода, остальное будет отфильтровано как мусор.

Вот как Опера внутри себя выкручивается с генерируемым контентом для <img>... впрочем, это ее личный выбор и трудности :)

Link to comment
Share on other sites

s0rr0w,

Так всё же ты говоришь - нет? Или есть исключения? Т.е. могу ли я всё же позволить себе незакрывать теги, если я этого захочу? Т.е. на сколько критично это скажется на последующем програминге и поддержке сайта? Может быть ты снова говоришь об интерфесах, а не об обычных джиквери-сайтах?

SelenIT,

И для XML-парсера абсолютно пофиг, закрыт <p> явно или автоматически - ему достаточно, что это не XML.

Да, но почему тогда ребята спорят и говорят обратное?

Link to comment
Share on other sites

Писать так нельзя :), но парсер не умрет, встретив такую бяку. В DOM попадут картинка и текстовая нода, остальное будет отфильтровано как мусор.

Беда в том, что при таком молчаливом поведении парсера никто не узнает про тот факт, что так делать нельзя. Вернее многие начнут думать, что так делать можно, ведь браузер что-то отображает, значит этот код правильный.

Так всё же ты говоришь - нет? Или есть исключения? Т.е. могу ли я всё же позволить себе незакрывать теги, если я этого захочу? Т.е. на сколько критично это скажется на последующем програминге и поддержке сайта? Может быть ты снова говоришь об интерфесах, а не об обычных джиквери-сайтах?

В спецификации написано что можно, значит можно. Но лучше стремиться к порядку в голове и коде и все же закрывать все теги.

Link to comment
Share on other sites

В спецификации написано что можно, значит можно. Но лучше стремиться к порядку в голове и коде и все же закрывать все теги.

Спасибо, понял. Но, если честно, то мне не в западло закрывать все теги, кроме списочных, они доставляют мне ряд хлопот, порой очень неприятных. Вот, как думаешь, если не закрывать только лишь <li>, где мне нужно - это сильно навредит или создаст проблем?

Link to comment
Share on other sites

многие начнут думать, что так делать можно, ведь браузер что-то отображает

Умных насторожит явное несоответствие отображаемого чего-то задуманному. А дурака и "желтый экран смерти" не остановит - он до последнего будет винить браузер, коннект, фазы луны и т.п., только не свои руки и извилины... :)

лучше стремиться к порядку в голове и коде и все же закрывать все теги

Вот не могу я согласиться, что закрытие всех тегов - показатель порядка. Напротив, привычка закрывать теги бездумно и на автомате скорее может породить того уродца с </img>.

Имхо, в коде всё должно быть по делу, и все закрывающие теги должны действительно что-то закрывать (как </div>), а не "делать вид, что закрывают"...

Link to comment
Share on other sites

Нашел одну штуку. Если когда то вернуться к xHTNL18, а ведь мы знаем, что это не исключено, то портировать без переделывания код не получится, а вот закрой теги - катается во все стороны без проблем. Довод называется "лучше перестраховаться чем недостраховаться", нужное заменить :)

Link to comment
Share on other sites

xHTNL18

Что за неведома зверушка?

а вот закрой теги - катается во все стороны без проблем

Если речь о предполагаемой ("возможно, когда-нибудь в будущем...") миграции на XML-сериализацию, то отнюдь нифига. Нужно еще ручками дописать все недостающие неймспейсы (особенно корневой), завернуть все скрипты и стили в CDATA, поставить правильный атрибут для языка и т.п. Но такое преобразование (как и обратное) делается в два счета средствами DOM, стандартными средствами той же html5lib и даже библиотек попроще. Уже сейчас.

Имхо, 12 лет бесплодных попыток W3C скрестить ежа с ужом (помехоустойчивость и простоту HTML для пользователя ценой сложности для парсера с простотой XML для парсера и кодера ценой выноса сложности в кучу добавочных соглашений "за скобками") - достаточный срок, чтобы признать: HTML и XML - разные вещи, требующие существенно разного подхода. И "совместимость" одного с другим и обратно - миф. И чем пытаться усидеть на двух стульях, тратя время и силы не "неукоснительное соблюдение взаимоисключающих параграфов", не лучше ли полнее использовать преимущества каждой из технологий в той сфере, где она сильнее всего (HTML - как твердой, надежной и стандартной основы представления инфы для конечного пользователя, XML - как гибкий, универсальный и стандартный связующий механизм для гетерогенных систем)?

Одно из таких преимуществ HTML - возможность не закрывать определенные теги (без ущерба для дела), одно из преимуществ XML - возможность закрывать любые теги любым способом (хоть <img/>, хоть <img></img>)... :)

Link to comment
Share on other sites

xHTNL18 - возможная реинкарнация.

Ничего подобного делать не надо, просто поменять 1 строку в хедере и доктайп (самое сложное - групповым поиском и заменой, а если сайт на движке - 1 раз в обертке), про явакскипт - до конца не уверен, но я никогда вообще не экранировал и никогда не было проблем.

Зато я помню, как я мучался, когда сайт, написанный на никаком хтмл, только набор тегов незакрытых в квиркмоде, надо было рефакторить. Библиотеки, да, но все равно, после этого надой зайти, как минимум и посмотреть, библиотека она же эта, людьми написана, они могут не предусмотреть какой-то момент, который потом может весь дом разорвать, а просто хмл подобный код не надо, если не было правок в цсс. Портировал и все.

Ноя вижу что это холиварный вопрос и относится к манере разработки, наверное. Кто как привык. Мне легче все закрыть и структуру видеть, ошибки отлавливать легче.

По холивару: Я уже высказывался когда-то, и теперь еще раз скажу, эти скоты, чтобы выиграть непонятно что (а ведь ничего не выиграно, просто незакрытый тег и все, функционала это действо не добавляет) ввели ограничения, например, в абзац нельзя вставить див, ул, и любой другой блочный элемент. Потом вспохватились что создав параграф по сути его имели ввиду как абзац и понеслась недосемантика, которую они тоже не могут оформить. В Самую основополагающую конструкцию сразу заложили ущербность, понятное дело, будь то хмл-подобный синтаксис, этого бы не произошло.

Если в магазине 2 стойки под ТВ, одинаковые абсолютно по цене, но одна твердостоящая и незыблимая, а вторая трехногая или, упаси, двуногая с гироскопом, в общем, те, которые ребенок пробегая мимо наклонит и ТВ дорогой улетит "в пропасть" - то я выберу первую, эстеты могут выбрать вторую и обрекут себя либо в барьере защитном с паддингом 2 метра держать, либо собаку злую сожать чтоб никто не подходил, либо ребенка ругать постоянно. Трагедия, с далеко идущими последователями. Потому адептов незакрываемых тегов я не понимаю. Если я задам Вам вопрос - почему же не надо закрывать, боюсь не услышать чего-то стоящего, твердого, внятного и вразумительного.

UPD:

про скрипты, их вообще никто не запрещает держать в отдельных файлах, наоборот, только советуют :)

UPD2:

При разработке движком, уверен почему-то, разрабы все равно будут сматреть в сторону хмл, даже хтмл в незакрытыми тегами, все равно хмл подобный, можно ведь рассуждать как: просто прописаны условия, что некоторые теги одиночные, надо мысленно держать закрывающий, а ведь так и есть, вы же не будете спорить, что незакрытый ли именно закрывается перед объявлением следующего ли?

И им приджется это иметь ввиду, писать обработчики исключений. И они тоже заложники, мне их искренне жаль :)

UPD3:

Почитал название ветки и понял, что я не отвечал почти на Ваш вопрос :) Точнее, только часть про рефакторинг - да, было. Это конечно мало вероятно, если все везде "то что доктор прописал", на каждом этапе разработки проекта, но ведь везде есть человеческий фактор, заболел верстальщик - верстать заставили программиста, он в своей убунте все увидел че хотел и забыл. Ну, наверное тут понятно :)

Link to comment
Share on other sites

Ничего подобного делать не надо, просто поменять 1 строку в хедере и доктайп (самое сложное - групповым поиском и заменой, а если сайт на движке - 1 раз в обертке), про явакскипт - до конца не уверен, но я никогда вообще не экранировал и никогда не было проблем.

Сорри, но по-моему как раз вот это - пример тяп-ляп-подхода. "До конца не уверен, но вроде всегда работало..." А если будет честный application/xhtml+xml, а в скрипте знак "<" затесался? ;)

эти скоты, чтобы выиграть непонятно что ... ввели ограничения

По-моему, поначалу абзац, пункт списка и т.п. вообще рассматривались не как контейнеры, а как что-то типа пунктуации (вот как в ворде есть символ абзаца, который ^p, иногда еще как ¶ отображается - вот так и <P> рассматривался). Потом уже удачно SGML вспомнили и туда же привязали, оттуда закрывающие теги подтянулись, а с ними и восприятие элемента как контейнера, мысли о его семантике и, в конечном счете, идея XML :). Но браузеры, в которых абзац воспринимался как "от ¶ до ¶" всё равно уже были...

А английское paragraph - это наш абзац ("красная строка" по-школьному) и есть. Наш параграф по-ихнему section, в <section> блоки вкладывать можно :)

Если я задам Вам вопрос - почему же не надо закрывать

Во-первых, 16 элементов закрывать запрещено. Почему - по спецификации :). И чтобы подчеркнуть их особый статус, что у них ни при каких условиях не может быть контента (см. выше пример s0rr0w с <img>...</img>).

Во-вторых, как ни забавно, конструкция на трех ножках в общем случае-таки устойчивее, чем на 4-х :), и в ситуации "а-ля ворд"

<p>текст раз <p>текст два <!-- конец документа -->
мы с CSS-движком всегда можем рассчитывать на два простых и надежных, как лопата, блочных бокса подряд, весь текст в надежной "упаковке" и легко управляем. В отличие от XML-образной радости типа
<p>текст раз</p> ой, а это еще что<p>текст два</p>
где между этими блоками ВНЕЗАПНО111 появляется неведома зверушка без роду и племени, вокруг которой приходится спешно городить огород из анонимных боксов (с неуправляемыми дефолтными отступами и т.п.). Это, конечно, проблемы главным образом CSS-движка, но сам факт таких сюрпризов как-то не радует.

Собственно, главная мысль, которую я хочу донести: закрытие всех тегов - не панацея и не гарантия отсутствия проблем. И при явно закрытых, и при неявно закрытых элементах всё равно нужно думать о структуре разметки и понимать ее. Но механическое закрытие тегов может создавать иллюзию контроля и безопасности, с которой будет больно расставаться. Особенно если автор думает, что пишет страницу на одном языке, а парсер "думает", что читает ее на совсем другом (как одно и то же слово Gift по-английски - "подарок", а по-немецки - "яд", а слово "глюк" по-немецки - "счастье", а по-нашему...) :)

Я не "фанат незакрытия тегов везде, где можно", сам не закрываю только тогда, когда это приносит явное упрощение и удобство (те же инлайн-блоки). Но фанатизм в стиле "не надо думать, закрывать надо!" считаю как минимум не менее вредным. Поэтому и выступаю тут в роли "адвоката дьявола" (а на деле никакого не дьявола, а обычного, да, в неумелых руках - потенциально опасного, но в умелых руках и к месту полезного и удобного - инструмента)...

надо мысленно держать закрывающий, а ведь так и есть, вы же не будете спорить, что незакрытый ли именно закрывается перед объявлением следующего ли?

И им приджется это иметь ввиду, писать обработчики исключений.

Всё так и есть. Только этот алгоритм, со всеми исключениями, уже написан. И реализован в 2 с половиной браузерах из 5 основных (FF4+, Хром 7+, Опера 12+). И это - реальность.

Кстати, XML - тоже реальность, причем гораздо более давняя. Но почему-то желающих работать только в этой симпатичной реальности немного, все больше норовят навязать чужие правила несчастному "старичку" HTML... :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy